#include <iostream>
#include <vector>
#include <string>
#include <iomanip>
#include <sstream>
#include <fstream>

using namespace std;

// 账单结构体：包含所有必要信息
struct Bill {
    char type;       // 'I'表示收入，'E'表示支出
    string date;     // 日期：YYYY-MM-DD
    double money;    // 金额（正数）
    string kind;     // 类别（工资/餐饮等）
    string note;     // 备注
};

// 预算结构体
struct Budget {
    string month;    // 月份：YYYY-MM
    double limit;    // 预算限额
};

// 全局变量存储数据
vector<Bill> allBills;    // 所有账单
vector<Budget> allBudgets;// 所有预算

// 函数声明（按功能分类）
void showMenu();                  // 显示菜单
void addIncome();                 // 记录收入
void addExpense();                // 记录支出
void showAll();                   // 显示所有账单
void queryBills();                // 查询账单
void setBudget();                 // 设置预算
void showReport();                // 月度统计
bool checkDate(string date);      // 检查日期格式
bool checkMoney(double money);    // 检查金额是否合法
void saveData();                  // 保存数据
void loadData();                  // 加载数据

int main() {
    loadData();  // 启动时加载已保存的数据
    int choice;

    while (true) {
        showMenu();
        cin >> choice;
        cin.ignore();  // 清除输入缓冲区的回车

        // 根据选择执行对应功能
        switch (choice) {
        case 1: addIncome(); break;
        case 2: addExpense(); break;
        case 3: showAll(); break;
        case 4: queryBills(); break;
        case 5: setBudget(); break;
        case 6: showReport(); break;
        case 7:
            saveData();  // 退出前保存数据
            cout << "谢谢使用，再见！" << endl;
            return 0;
        default:
            cout << "输入错误，请重新选择！" << endl;
            system("pause");  // 暂停一下让用户看清提示
        }
    }
}

// 显示主菜单
void showMenu() {
    system("cls");  // 清屏（Windows系统，Linux用"clear"）
    cout << "============================" << endl;
    cout << "      个人账单管理系统      " << endl;
    cout << "============================" << endl;
    cout << "1. 记录收入" << endl;
    cout << "2. 记录支出" << endl;
    cout << "3. 查看所有账单" << endl;
    cout << "4. 查询账单" << endl;
    cout << "5. 设置月度预算" << endl;
    cout << "6. 查看月度统计" << endl;
    cout << "7. 退出系统" << endl;
    cout << "============================" << endl;
    cout << "请输入选项(1-7)：";
}

// 记录收入
void addIncome() {
    system("cls");
    Bill b;
    b.type = 'I';  // 收入类型标记

    cout << "===== 记录收入 =====" << endl;

    // 输入日期（带格式检查）
    while (true) {
        cout << "请输入日期(YYYY-MM-DD)：";
        getline(cin, b.date);
        if (checkDate(b.date)) break;
        else cout << "日期格式错误！请重新输入" << endl;
    }

    // 输入金额（带合法性检查）
    while (true) {
        cout << "请输入收入金额：";
        cin >> b.money;
        if (checkMoney(b.money)) break;
        else cout << "金额必须是正数！请重新输入" << endl;
    }
    cin.ignore();  // 清除缓冲区

    // 输入类别和备注
    cout << "请输入收入类别(如：工资、奖金)：";
    getline(cin, b.kind);
    cout << "请输入备注(可选)：";
    getline(cin, b.note);

    // 保存到账单列表
    allBills.push_back(b);
    cout << "收入记录成功！" << endl;
    system("pause");
}

// 记录支出
void addExpense() {
    system("cls");
    Bill b;
    b.type = 'E';  // 支出类型标记
    cout << "===== 记录支出 =====" << endl;
    // 输入日期
    while (true) {
        cout << "请输入日期(YYYY-MM-DD)：";
        getline(cin, b.date);
        if (checkDate(b.date)) break;
        else cout << "日期格式错误！请重新输入" << endl;
    }
    while (true) {
        cout << "请输入支出金额：";
        cin >> b.money;
        if (checkMoney(b.money)) break;
        else cout << "金额必须是正数！请重新输入" << endl;
    }
    cin.ignore();

    // 输入类别和备注
    cout << "请输入支出类别(如：餐饮、交通)：";
    getline(cin, b.kind);
    cout << "请输入备注(可选)：";
    getline(cin, b.note);

    // 保存到账单列表
    allBills.push_back(b);
    cout << "支出记录成功！" << endl;
    system("pause");
}
// 检查日期格式（简单验证）
bool checkDate(string date) {
    // 格式必须是YYYY-MM-DD（长度10，第5和第8位是'-'）
    if (date.size() != 10 || date[4] != '-' || date[7] != '-') {
        return false;
    }
    // 月份必须是01-12，日期必须是01-31（简化检查）
    string month = date.substr(5, 2);
    string day = date.substr(8, 2);
    if (month < "01" || month > "12") return false;
    if (day < "01" || day > "31") return false;
    return true;
}

// 检查金额是否为正数
bool checkMoney(double money) {
    return money > 0;
}


